{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**问题：**\n",
    "假设你正在为一个电影推荐系统设计一个简单的KNN算法。我们有以下一些用户的电影评分数据，数据由两个特征组成：用户对电影A和电影B的评分，分别在1-5之间。用户的标签（电影类型偏好）是动作片（标签0）或者是喜剧片（标签1）。我们有一个新用户，他给电影A评分为3，电影B评分为4。请问这个用户可能偏好哪种类型的电影？\n",
    "\n",
    "**数据：**\n",
    "\n",
    "| 用户   | 电影A评分 | 电影B评分 | 偏好类型 |\n",
    "| ------ | --------- | --------- | -------- |\n",
    "| 用户1  | 5         | 1         | 动作片   |\n",
    "| 用户2  | 4         | 2         | 动作片   |\n",
    "| 用户3  | 2         | 5         | 喜剧片   |\n",
    "| 用户4  | 1         | 4         | 喜剧片   |\n",
    "| 用户5  | 3         | 2         | 动作片   |\n",
    "| 用户6  | 2         | 5         | 喜剧片   |\n",
    "\n",
    "你需要做以下步骤：\n",
    "1. 构造数据\n",
    "2. 创建KNN模型\n",
    "3. 使用数据训练模型\n",
    "4. 预测新用户的喜好"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 0. 引入核心包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from sklearn.neighbors import KNeighborsClassifier"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 1. X, y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = np.array([(5,1),\n",
    "              (4,2),\n",
    "              (2,5),\n",
    "              (1,4),\n",
    "              (3,2),\n",
    "              (2,5)])\n",
    "\n",
    "y = np.array([0,0,1,1,0,1]) # 0表示动作片，1表示喜剧片\n"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 2. 创建 KNN 模型\n",
    "k = 1"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "knn = KNeighborsClassifier(n_neighbors=1)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 3. 训练模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<style>#sk-container-id-1 {color: black;}#sk-container-id-1 pre{padding: 0;}#sk-container-id-1 div.sk-toggleable {background-color: white;}#sk-container-id-1 label.sk-toggleable__label {cursor: pointer;display: block;width: 100%;margin-bottom: 0;padding: 0.3em;box-sizing: border-box;text-align: center;}#sk-container-id-1 label.sk-toggleable__label-arrow:before {content: \"▸\";float: left;margin-right: 0.25em;color: #696969;}#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {color: black;}#sk-container-id-1 div.sk-estimator:hover label.sk-toggleable__label-arrow:before {color: black;}#sk-container-id-1 div.sk-toggleable__content {max-height: 0;max-width: 0;overflow: hidden;text-align: left;background-color: #f0f8ff;}#sk-container-id-1 div.sk-toggleable__content pre {margin: 0.2em;color: black;border-radius: 0.25em;background-color: #f0f8ff;}#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {max-height: 200px;max-width: 100%;overflow: auto;}#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {content: \"▾\";}#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 input.sk-hidden--visually {border: 0;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);height: 1px;margin: -1px;overflow: hidden;padding: 0;position: absolute;width: 1px;}#sk-container-id-1 div.sk-estimator {font-family: monospace;background-color: #f0f8ff;border: 1px dotted black;border-radius: 0.25em;box-sizing: border-box;margin-bottom: 0.5em;}#sk-container-id-1 div.sk-estimator:hover {background-color: #d4ebff;}#sk-container-id-1 div.sk-parallel-item::after {content: \"\";width: 100%;border-bottom: 1px solid gray;flex-grow: 1;}#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {background-color: #d4ebff;}#sk-container-id-1 div.sk-serial::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: 0;}#sk-container-id-1 div.sk-serial {display: flex;flex-direction: column;align-items: center;background-color: white;padding-right: 0.2em;padding-left: 0.2em;position: relative;}#sk-container-id-1 div.sk-item {position: relative;z-index: 1;}#sk-container-id-1 div.sk-parallel {display: flex;align-items: stretch;justify-content: center;background-color: white;position: relative;}#sk-container-id-1 div.sk-item::before, #sk-container-id-1 div.sk-parallel-item::before {content: \"\";position: absolute;border-left: 1px solid gray;box-sizing: border-box;top: 0;bottom: 0;left: 50%;z-index: -1;}#sk-container-id-1 div.sk-parallel-item {display: flex;flex-direction: column;z-index: 1;position: relative;background-color: white;}#sk-container-id-1 div.sk-parallel-item:first-child::after {align-self: flex-end;width: 50%;}#sk-container-id-1 div.sk-parallel-item:last-child::after {align-self: flex-start;width: 50%;}#sk-container-id-1 div.sk-parallel-item:only-child::after {width: 0;}#sk-container-id-1 div.sk-dashed-wrapped {border: 1px dashed gray;margin: 0 0.4em 0.5em 0.4em;box-sizing: border-box;padding-bottom: 0.4em;background-color: white;}#sk-container-id-1 div.sk-label label {font-family: monospace;font-weight: bold;display: inline-block;line-height: 1.2em;}#sk-container-id-1 div.sk-label-container {text-align: center;}#sk-container-id-1 div.sk-container {/* jupyter's `normalize.less` sets `[hidden] { display: none; }` but bootstrap.min.css set `[hidden] { display: none !important; }` so we also need the `!important` here to be able to override the default hidden behavior on the sphinx rendered scikit-learn.org. See: https://github.com/scikit-learn/scikit-learn/issues/21755 */display: inline-block !important;position: relative;}#sk-container-id-1 div.sk-text-repr-fallback {display: none;}</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>KNeighborsClassifier(n_neighbors=1)</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label sk-toggleable__label-arrow\">KNeighborsClassifier</label><div class=\"sk-toggleable__content\"><pre>KNeighborsClassifier(n_neighbors=1)</pre></div></div></div></div></div>"
      ],
      "text/plain": [
       "KNeighborsClassifier(n_neighbors=1)"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "knn.fit(X, y)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 4. 用模型推理(预测)用户的喜好"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "new_user = np.array([[3, 4]])\n",
    "prediction = knn.predict(new_user)"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 5. 数据可视化"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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mwXcUIuI/k8U3sDDAw8vX1oMn1x2QYlcj664yiz/yFDuP/6RN8n6uefy1ouIFIPTjhQV52nTgwcPplatWsyYMQOAJ598ki5duvDqq6/Sp08fFi1axObNm3n33XfLPH6Ahv3+jpdfBX7/7A0uX8jA5OllPloUVKs+kY++RMU6jZ0Sm8h14erL7q+ciJl/hOi55yzfi4gUwulXnxUlOTnZ/DBVgE6dOhEfH8+kSZOYOHEiDRs2ZMmSJQWKq7JiMpm4secDhN/en5SfE0hNOcheIGrCAm6IiMRUzGc0iUgJFOc+RCqMRMQG5aoouvpp09aePt2/f3/659+wrZzw9PGj9s13Uj07m71Ll1K5QQsVRCKOlpNTvPsQ5a/PyXF8TCLi0spVUSQiUmzXeLirBR0hEpFicPodrUVERETKAxVFIiIiIqgoEhEREQFUFImIiIgAKopEREREABVFIiIiIoCKIhERERFARZGIiIgIoKJIREREBFBRJCIiIgKoKBIREREBVBSJiIiIACqKRERERAAVRSIiIiKAiiIRERERQEWRiIiICKCiSERERARQUSQiIiICqCgSERERAVQUiYiIiAAqikREREQAFUUiIiIigIoiEREREUBFkYiIiAigokhEREQEUFEkIiIiAqgoEhEREQFUFImIiIgA4GXrBk8//bTV5SaTCT8/Pxo0aEC/fv2oUqVKqYMTERERKSs2F0Xbtm1j69at5OTk0LhxYwD++OMPPD09iYiI4O233+aZZ55h3bp13HTTTXYPWERERMQRbD591q9fP+644w6OHTvGli1b2LJlC0eOHCE6OprY2FiOHj3KrbfeylNPPXXNvubMmUOLFi0IDg4mODiYqKgoli1bVmj7uLg4TCaTxcvPz8/WFEREREQKsPlI0cyZM0lISCA4ONi8rGLFikyZMoXu3bvz5JNP8txzz9G9e/dr9lW7dm1eeuklGjZsiGEYvP/++/Tr149t27bRtGlTq9sEBweze/du83uTyWRrCiIiIiIF2FwUpaamcvLkyQKnxv7880/S0tIAqFSpEpcuXbpmX3feeafF+xdeeIE5c+bw448/FloUmUwmQkNDbQ1bREREpEg2F0X9+vVj2LBhvPrqq7Rr1w6ATZs2MWbMGGJiYgD4+eefadSokU395uTk8Nlnn3H+/HmioqIKbZeRkUF4eDi5ublERkby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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.title(\"User Movie Preference\", size=15) \n",
    "plt.xlabel(\"Movie A rating\")\n",
    "plt.ylabel(\"Movie B rating\")\n",
    "plt.grid()\n",
    "\n",
    "# 绘制原始样本点，要求不同的影片喜好类别用不同的颜色标记\n",
    "# 提示: 用scatter散点图绘制，用它的参数c实现不同的类别用不同的颜色标记\n",
    "plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired, s=50)\n",
    "\n",
    "# 绘制新数据点，用红色x标记，大小为8\n",
    "# 提示：用plt.plot()绘制，用它的参数marker实现不同的标记符号\n",
    "plt.plot(new_user[0, 0], new_user[0, 1], 'rx', markersize=8)\n",
    "\n",
    "# 新数据最近邻索引为第一个最近邻的索引\n",
    "dist, idx = knn.kneighbors(new_user, n_neighbors=1)\n",
    "nearest = X[idx[0][0]]# 获取最近邻点的坐标，这是一个列表，第一个元素是x坐标，第二个元素是y坐标\n",
    "\n",
    "# 用红线标记新数据点与最近邻点的连接线\n",
    "# 提示：用plt.plot()绘制，用 r-- 实现红色虚线\n",
    "plt.plot([new_user[0, 0], nearest[0]], [new_user[0, 1], nearest[1]], 'r--')\n",
    "\n",
    "# 为每个点添加坐标文本  \n",
    "for x, y in zip(X[:, 0], X[:, 1]):\n",
    "    plt.text(x, y+0.1, f'({x}, {y})') \n",
    "\n",
    "# 为新数据点添加坐标文本\n",
    "plt.text(new_user[0,0], new_user[0,1]+0.1, f'({new_user[0,0]}, {new_user[0,1]})')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.11"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
